import type { App } from 'vue'
import {
  createRouter,
  createWebHashHistory,
  RouteLocationNormalized,
  RouteRecordRaw
} from 'vue-router'
import { ref } from 'vue'
import Home from '@views/index/index.vue'
import { SystemInfo } from '@/config/setting'
import { useUserStore } from '@/store/modules/user'
import { menuService } from '@/api/menuApi'
import { useMenuStore } from '@/store/modules/menu'
import { useSettingStore } from '@/store/modules/setting'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { useTheme } from '@/composables/useTheme'
import { RoutesAlias } from './modules/routesAlias'
import { setWorktab } from '@/utils/worktab'
import { registerAsyncRoutes } from './modules/dynamicRoutes'
import { formatMenuTitle } from '@/utils/menu'

/** 顶部进度条配置 */
NProgress.configure({
  easing: 'ease',
  speed: 600,
  showSpinner: false,
  trickleSpeed: 200,
  parent: 'body'
})

/** 扩展的路由配置类型 */
export type AppRouteRecordRaw = RouteRecordRaw & {
  hidden?: boolean
}

/** 首页路径常量 */
export const HOME_PAGE = '/dashboard/console'

/** 静态路由配置 */
const staticRoutes: AppRouteRecordRaw[] = [
  { path: '/', redirect: HOME_PAGE },
  {
    path: '/dashboard',
    component: Home,
    name: 'Dashboard',
    meta: { title: 'menus.dashboard.title' },
    children: [
      {
        path: RoutesAlias.Dashboard,
        name: 'Console',
        component: () => import('@views/dashboard/console/index.vue'),
        meta: { title: 'menus.dashboard.console', keepAlive: false }
      },
      {
        path: RoutesAlias.Analysis,
        name: 'Analysis',
        component: () => import('@views/dashboard/analysis/index.vue'),
        meta: { title: 'menus.dashboard.analysis', keepAlive: false }
      },
      {
        path: RoutesAlias.Ecommerce,
        name: 'Ecommerce',
        component: () => import('@views/dashboard/ecommerce/index.vue'),
        meta: { title: 'menus.dashboard.ecommerce', keepAlive: false }
      },
      
    ]
  },
  // 异常页面路由
  {
    path: '/exception',
    component: Home,
    name: 'Exception',
    meta: { title: 'menus.exception.title', isHideTab: true },
    children: [
      {
        path: '403',
        name: 'Exception403',
        component: () => import('@views/exception/403.vue'),
        meta: { title: 'menus.exception.notFound', isHideTab: true }
      },
      {
        path: '404',
        name: 'Exception404',
        component: () => import('@views/exception/404.vue'),
        meta: { title: 'menus.exception.notFound', isHideTab: true }
      },
      {
        path: '500',
        name: 'Exception500',
        component: () => import('@views/exception/500.vue'),
        meta: { title: 'menus.exception.serverError', isHideTab: true }
      }
    ]
  },
  {
    path: RoutesAlias.Login,
    name: 'Login',
    component: () => import('@views/login/index.vue'),
    meta: { title: 'menus.login.title', isHideTab: true, setTheme: true }
  },
  {
    path: RoutesAlias.Register,
    name: 'Register',
    component: () => import('@views/register/index.vue'),
    meta: { title: 'menus.register.title', isHideTab: true, noLogin: true, setTheme: true }
  },
  {
    path: RoutesAlias.ForgetPassword,
    name: 'ForgetPassword',
    component: () => import('@views/forget-password/index.vue'),
    meta: { title: 'menus.forgetPassword.title', isHideTab: true, noLogin: true, setTheme: true }
  },
  {
    path: '/outside',
    component: Home,
    name: 'Outside',
    meta: { title: 'menus.outside.title' },
    children: [
      {
        path: '/outside/iframe/:path',
        name: 'Iframe',
        component: () => import('@/views/outside/Iframe.vue'),
        meta: { title: 'iframe' }
      }
    ]
  }
]

/** 创建路由实例 */
export const router = createRouter({
  history: createWebHashHistory(),
  routes: staticRoutes,
  scrollBehavior: () => ({ left: 0, top: 0 })
})

// 标记是否已经注册动态路由
const isRouteRegistered = ref(false)
// 添加标记，跟踪菜单是否正在加载中
const isMenuLoading = ref(false)
// 菜单数据请求Promise
let menuDataPromise: Promise<void> | null = null;

/**
 * 路由全局前置守卫
 * 处理进度条、获取菜单列表、动态路由注册、404 检查、工作标签页及页面标题设置
 */
router.beforeEach(async (to, from, next) => {
  const settingStore = useSettingStore()
  if (settingStore.showNprogress) NProgress.start()

  // 设置登录注册页面主题
  setSystemTheme(to)

  // 检查登录状态，如果未登录则跳转到登录页
  const userStore = useUserStore()
  if (!userStore.isLogin && to.path !== '/login' && !to.meta.noLogin) {
    userStore.logOut()
    return next('/login')
  }

  // 如果用户已登录且动态路由未注册，则注册动态路由
  if (!isRouteRegistered.value && userStore.isLogin) {
    try {
      // 如果尚未加载菜单数据且没有进行中的请求，开始加载
      if (!menuDataPromise && !isMenuLoading.value) {
        isMenuLoading.value = true;
        menuDataPromise = getMenuData().finally(() => {
          isMenuLoading.value = false;
        });
      }
      
      // 等待菜单数据加载完成
      if (menuDataPromise) {
        await menuDataPromise;
        menuDataPromise = null; // 清空Promise引用
      }
      
      if (to.name === 'Exception404') {
        return next({ path: to.path, query: to.query, replace: true })
      } else {
        return next({ ...to, replace: true })
      }
    } catch (error) {
      console.error('Failed to register routes:', error)
      return next('/exception/500')
    }
  }

  // 检查路由是否存在，若不存在则跳转至404页面
  if (to.matched.length === 0) {
    return next('/exception/404')
  }

  // 设置工作标签页和页面标题
  setWorktab(to)
  setPageTitle(to)

  next()
})

/**
 * 根据接口返回的菜单列表注册动态路由
 * @throws 若菜单列表为空或获取失败则抛出错误
 */
async function getMenuData(): Promise<void> {
  // 如果路由已注册，直接返回
  if (isRouteRegistered.value) {
    console.log('路由已注册，跳过菜单请求');
    return;
  }

  try {
    console.log('开始获取菜单数据...');
    // 获取菜单列表
    const { menuList, closeLoading } = await menuService.getMenuList()
    console.log("获取菜单列表成功，数量:", menuList.length);
    
    // 如果菜单列表为空，执行登出操作并跳转到登录页
    if (!Array.isArray(menuList) || menuList.length === 0) {
      closeLoading()
      useUserStore().logOut()
      throw new Error('获取菜单列表失败，请重新登录！')
    }

    // 添加设备管理菜单及其子菜单
    const deviceManagementMenu = {
      id: 9000, // 使用较大ID避免冲突
      path: '/cloudDevice',
      name: 'CloudDevice',
      component: '/index/index',
      meta: {
        title: '设备管理',
        icon: '&#xe681;',
        keepAlive: true
      },
      children: [
        {
          id: 9001,
          path: '/cloudDevice/deviceManagement',
          name: 'DeviceManagement',
          component: '/cloudDevice/DeviceManagement',
          meta: {
            title: '设备管理',
            icon: '&#xe64d;',
            keepAlive: true
          }
        },
        {
          id: 9002,
          path: '/cloudDevice/deviceScan',
          name: 'DeviceScan',
          component: '/cloudDevice/DeviceScan',
          meta: {
            title: '设备扫描',
            icon: '&#xe7fa;',
            keepAlive: true
          }
        },
        {
          id: 9003,
          path: '/cloudDevice/androidVersionManagement',
          name: 'AndroidVersionManagement',
          component: '/deviceManagement/AndroidVersionManagement',
          meta: {
            title: '设备系统管理',
            icon: '&#xe6e0;',
            keepAlive: true
          }
        },
        {
          id: 9004,
          path: '/cloudDevice/bitrateManagement',
          name: 'BitrateManagement',
          component: '/cloudDevice/BitrateManagement',
          meta: {
            title: '画面参数管理',
            icon: '&#xe65a;',
            keepAlive: true
          }
        }
      ]
    };

    // 添加节点管理菜单
    const nodeManagementMenu = {
      id: 9100,
      path: '/nodeManagement',
      name: 'NodeManagement',
      component: '/index/index',
      meta: {
        title: '节点管理',
        icon: '&#xe6df;',
        keepAlive: true
      },
      children: [
        {
          id: 9101,
          path: '/nodeManagement/nodes',
          name: 'Nodes',
          component: '/nodeManagement/Nodes',
          meta: {
            title: '节点管理',
            icon: '&#xe6e2;',
            keepAlive: true
          }
        }
      ]
    };

    // 添加套餐管理菜单
    const packageManagementMenu = {
      id: 9200,
      path: '/packageManagement',
      name: 'PackageManagement',
      component: '/index/index',
      meta: {
        title: '套餐管理',
        icon: '&#xe62e;',
        keepAlive: true
      },
      children: [
        {
          id: 9201,
          path: '/packageManagement/packages',
          name: 'Packages',
          component: '/packageManagement/PackageManagement',
          meta: {
            title: '套餐配置',
            icon: '&#xe63e;',
            keepAlive: true
          }
        },
        {
          id: 9202,
          path: '/packageManagement/vipLevels',
          name: 'VipLevels',
          component: '/packageManagement/VipLevelManagement',
          meta: {
            title: '套餐等级管理',
            icon: '&#xe6db;',
            keepAlive: true
          }
        }
      ]
    };

    // 添加流量监控菜单
    const trafficManagementMenu = {
      id: 9300,
      path: '/trafficManager',
      name: 'TrafficManager',
      component: '/index/index',
      meta: {
        title: '流量管理',
        icon: '&#xe6e2;',
        keepAlive: true
      },
      children: [
        {
          id: 9301,
          path: '/trafficManager/monitor',
          name: 'TrafficMonitor',
          component: '/trafficManger/TrafficMonitor',
          meta: {
            title: '流量监控',
            icon: '&#xe6e2;',
            keepAlive: true
          }
        },
        {
          id: 9302,
          path: '/trafficManager/statistics',
          name: 'TrafficStatistics',
          component: '/trafficManger/TrafficStatistics',
          meta: {
            title: '流量统计',
            icon: '&#xe629;',
            keepAlive: true
          }
        }
      ]
    };

    // 添加用户管理菜单
    const userManagementMenu = {
      id: 9400,
      path: '/userManagement',
      name: 'UserManagement',
      component: '/index/index',
      meta: {
        title: '用户管理',
        icon: '&#xe646;',
        keepAlive: true
      },
      children: [
        {
          id: 9401,
          path: '/userManagement/users',
          name: 'Users',
          component: '/userManagement/UserList',
          meta: {
            title: '用户列表',
            icon: '&#xe646;',
            keepAlive: true
          }
        }
      ]
    };

    // 添加租用管理菜单
    const rentManagementMenu = {
      id: 9500,
      path: '/rentManagement',
      name: 'RentManagement',
      component: '/index/index',
      meta: {
        title: '租用管理',
        icon: '&#xe63e;',
        keepAlive: true
      },
      children: [
        {
          id: 9501,
          path: '/rentManagement/list',
          name: 'RentList',
          component: '/rentManagement/RentList',
          meta: {
            title: '租用列表',
            icon: '&#xe63e;',
            keepAlive: true
          }
        }
      ]
    };

    // 将设备管理菜单添加到菜单列表中
    // menuList.push(deviceManagementMenu);
    // menuList.push(nodeManagementMenu);
    // menuList.push(packageManagementMenu);
    // menuList.push(trafficManagementMenu); // 添加流量监控菜单到列表
    // menuList.push(userManagementMenu); // 添加用户管理菜单到列表
    // menuList.push(rentManagementMenu); // 添加租用管理菜单到列表
    console.log("添加菜单后的菜单数量:", menuList.length);

    // 设置菜单列表
    useMenuStore().setMenuList(menuList as [])
    // 注册异步路由
    registerAsyncRoutes(router, menuList)
    // 标记路由已注册
    isRouteRegistered.value = true
    // 关闭加载动画
    closeLoading()
    console.log('菜单加载和路由注册完成');
  } catch (error) {
    console.error('获取菜单列表失败:', error)
    throw error
  }
}

/* ============================
   路由守卫辅助函数
============================ */

/**
 * 根据路由元信息设置系统主题
 * @param to 当前路由对象
 */
const setSystemTheme = (to: RouteLocationNormalized): void => {
  if (to.meta.setTheme) {
    useTheme().switchTheme(useSettingStore().systemThemeType)
  }
}

/**
 * 设置页面标题，根据路由元信息和系统信息拼接标题
 * @param to 当前路由对象
 */
export const setPageTitle = (to: RouteLocationNormalized): void => {
  const { title } = to.meta
  if (title) {
    setTimeout(() => {
      document.title = `${formatMenuTitle(String(title))} - ${SystemInfo.name}`
    }, 150)
  }
}

/** 路由全局后置守卫 */
router.afterEach(() => {
  if (useSettingStore().showNprogress) NProgress.done()
})

/**
 * 初始化路由，将 Vue Router 实例挂载到 Vue 应用中
 * @param app Vue 应用实例
 */
export function initRouter(app: App<Element>): void {
  app.use(router)
}
